package cn.jtfadmin.core.modules.range;


import cn.jtfadmin.base.data.jpa.range.JpaDataRangeRule;
import cn.jtfadmin.base.lang.common.domain.dto.AntdvTreeDataRDTO;
import cn.jtfadmin.base.lang.common.security.UserDetails;
import cn.jtfadmin.base.lang.config.ApplicationHolder;
import cn.jtfadmin.base.lang.config.user.UserHolder;
import cn.jtfadmin.core.config.shiro.UserDetailsPropertiesKey;
import cn.jtfadmin.core.modules.sys.domain.dto.UserMenuRDTO;
import cn.jtfadmin.core.modules.sys.domain.entity.SysPermissionEntity;
import cn.jtfadmin.core.modules.sys.utils.SysUserDetailUtil;
import org.apache.shiro.authc.UnknownAccountException;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.*;

/**
 * 权限数据范围
 */
@Component
@Aspect
public class SysPermissionDataRangeRule implements JpaDataRangeRule<SysPermissionEntity> {


    public static final String all = "1";

    public static final String user = "2";


    @Override
    public String getName() {
        return "sysPermission";
    }

    @Override
    public String getDisplayName() {
        return "菜单权限数据范围";
    }


    @Override
    public List<AntdvTreeDataRDTO> getAntdTreeDataRDTO() {
        UserDetails userDetails = UserHolder.getUserDetails();
        if (Objects.isNull(userDetails)) {
            throw new UnknownAccountException("用户未登录");
        }

        return Arrays.asList(
                new AntdvTreeDataRDTO("所有菜单权限", all, null),
                new AntdvTreeDataRDTO("本人菜单权限", user, null)
        );
    }


    @Override
    public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) {
        UserDetails userDetails = UserHolder.getUserDetails();
        if (Objects.isNull(userDetails)) {
            return null;
        }
        Class<?> javaType = root.getJavaType();
        if (javaType != SysPermissionEntity.class) {
            return null;
        }
        // 非系统用户不过滤
        if (!UserDetailsPropertiesKey.TYPE.equals(userDetails.getType())) {
            return null;
        }
        Set<String> permissionDataRule = SysUserDetailUtil.getPermissionDataRule(userDetails);
        if (permissionDataRule.contains(all)) {
            return null;
        }
        CriteriaBuilder.In<Object> in = criteriaBuilder.in(root.get("id"));
        UserMenuRDTO userMenuRDTO = SysUserDetailUtil.getUserMenu(userDetails);
        if (Objects.isNull(userMenuRDTO)) {
            return in;
        }
        List<UserMenuRDTO.MenuModelRDTO> menu = userMenuRDTO.getMenu();
        if (Objects.isNull(menu)) {
            return in;
        }
        List<UserMenuRDTO.AuthMenuRDTO> auth = userMenuRDTO.getAuth();
        List<String> ids = new ArrayList<>();
        fillPermissionId(menu, ids);
        for (String id : ids) {
            in.value(id);
        }
        if(Objects.nonNull(auth)){
            for (UserMenuRDTO.AuthMenuRDTO authMenuRDTO : auth) {
                in.value(authMenuRDTO.getId());
            }
        }

        return in;
    }




    private void fillPermissionId(List<UserMenuRDTO.MenuModelRDTO> menu, List<String> store) {
        for (UserMenuRDTO.MenuModelRDTO menuModelRDTO : menu) {
            store.add(menuModelRDTO.getId());
            if (!CollectionUtils.isEmpty(menuModelRDTO.getChildren())) {
                fillPermissionId(menuModelRDTO.getChildren(), store);
            }
        }
    }
}
